package com.hypo.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 1、类需要给SpringIOC容器管理
 * 2、类上添加注解@Aspect
 * 3、编写方法，方法上添加注解@Around，方法入参ProceedingJoinPoint
 * 4、在方法执行前，获取系统时间（目标方法调用前的时间）
 * 5、执行目标方法
 * 6、获取系统时间，并将当前系统时间-前面开始时间，得到方法执行耗时时间
 * 7、返回一个object对象
 */
//@Component
//@Aspect
@Slf4j
public class RecordTimeAspect {
    /**
     * @Around：环绕通知（将用户调用的方法，拿到这儿调用）
     * 切入点表达式：* com.hypo.service.impl.*.*(..)要对方法增强的匹配公式
     * 修饰符 返回值 方法所在的包名.方法所在的类名.方法名（..）
     * 修饰符可以省略
     * ()：表示方法
     * (..)：表示方法的任意参数（任意类型、任意个数）
     * ..：代表任意包路径@Around("execution(* com.hypo..*.*(..))")
     * *：可以代表任意返回类型，还可以代表任意接口或者任意类，还可以代表任意方法名字
     */
    @Around("execution(* com.hypo.service.impl.*.*(..))")
    public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
        //方法执行前，获取系统时间（目标方法调用前的时间）
        long begin = System.currentTimeMillis();
        //执行目标方法（删除员工、新增员工..），对目标方法调用
        Object proceed = pjp.proceed();
        //取系统时间，并将当前系统时间-前面开始时间，得到方法执行耗时时间
        long end = System.currentTimeMillis();
        //获取方法名
        String methodName = pjp.getSignature().getName();
        //打印执行时间
        log.info("{}方法执行耗时：{}毫秒",methodName,end-begin);
        //返回一个object对象
        return proceed;
    }
}
